#include "..\\Common\\DSExceptions.h"

#ifdef __cplusplus
	#define EXTERNC extern "C"
#else
	#define EXTERNC
#endif

#ifdef _WIN32
	#ifdef DATASTRUCTUREDLL_EXPORT
		#define DATASTRUCTUREAPI __declspec(dllexport)
	#else
		#define DATASTRUCTUREAPI  __declspec(dllimport)
	#endif
#else
	#define DATASTRUCTUREAPI
#endif

#if defined(_WIN64)
	typedef __int64 LONG_PTR;
	typedef unsigned __int64 ULONG_PTR;

	typedef __int64 INT_PTR;
	typedef unsigned __int64 UINT_PTR;
#else
	typedef long LONG_PTR;
	typedef unsigned long ULONG_PTR;

	typedef int INT_PTR;
	typedef unsigned int UINT_PTR;
#endif

#ifndef NULL
	#ifdef __cplusplus
		#define NULL    0
	#else
		#define NULL    ((void *)0)
	#endif
#endif

#define IS_NULL(UINT_PTR_VALUE) (((void*)UINT_PTR_VALUE) == NULL ? true : false)
#define IS_NOT_NULL(UINT_PTR_VALUE) (((void*)UINT_PTR_VALUE) != NULL ? true : false)

enum EDSType {
	eDSTYPE_NONE,
	eDSTYPE_ARRAY_STACK,
	eDSTYPE_CONCURRENT_ARRAY_STACK,
	eDSTYPE_LINKED_STACK,
	eDSTYPE_CONCURRENT_LINKED_STACK,
	eDSTYPE_ARRAY_QUEUE,
	eDSTYPE_CONCURRENT_ARRAY_QUEUE,
	eDSTYPE_LINKED_QUEUE,
	eDSTYPE_CONCURRENT_LINKED_QUEUE
};

enum EDataType {
	eDATATYPE_NONE,
	eDATATYPE_INTEGER,
	eDATATYPE_LONG,
	eDATATYPE_PTR
};

typedef struct _DSHandle {
	bool bValid;
	UINT_PTR ptrBinder;
	EDSType eDSType;
	EDataType eDataType;
	int nMaxSize;
}DSHandle, *LPDSHandle;

EXTERNC {
	//COMMON
	DATASTRUCTUREAPI bool createDS(DSHandle *a_hDS);
	DATASTRUCTUREAPI bool destroyDS(DSHandle *a_hDS);

		//TYPE SPECIFIC : INTEGER STACK
		DATASTRUCTUREAPI void setDefaultIntegerArrayStackHandle(DSHandle* a_phDS, int a_nSize, bool a_bConcurrent);
		DATASTRUCTUREAPI void setDefaultIntegerLinkedStackHandle(DSHandle* a_phDS, int a_nMaxSize, bool a_bConcurrent);
		DATASTRUCTUREAPI void pushIntStack(DSHandle *a_hDS, int a_nData);
		DATASTRUCTUREAPI int popIntStack(DSHandle *a_hDS);
		DATASTRUCTUREAPI bool canPushIntStack(DSHandle *a_hDS);
		DATASTRUCTUREAPI bool canPopIntStack(DSHandle *a_hDS);
		DATASTRUCTUREAPI int getDataCountIntStack(DSHandle *a_hDS);

		//TYPE SPECIFIC : INTEGER Queue
		DATASTRUCTUREAPI void setDefaultIntegerArrayQueueHandle(DSHandle* a_phDS, int a_nSize, bool a_bConcurrent);
		DATASTRUCTUREAPI void setDefaultIntegerLinkedQueueHandle(DSHandle* a_phDS, int a_nMaxSize, bool a_bConcurrent);
		DATASTRUCTUREAPI void offerIntQueue(DSHandle *a_hDS, int a_nData);
		DATASTRUCTUREAPI int pollIntQueue(DSHandle *a_hDS);
		DATASTRUCTUREAPI int peekIntQueue(DSHandle *a_hDS);
		DATASTRUCTUREAPI bool canOfferIntQueue(DSHandle *a_hDS);
		DATASTRUCTUREAPI bool canPollIntQueue(DSHandle *a_hDS);
		DATASTRUCTUREAPI int getDataCountIntQueue(DSHandle *a_hDS);
		
};
